#include "StdAfx.h"
#include "AIAgent.h"
#include "ActionObject.h"
#include "PhysicalObject.h"
#include "IRaceController.h"
#include "BoundingVolume.h"
#include "IMovable.h"
#include "Gate.h"
#include <math.h>


///////////////////////////////////////////////////////////////////////////////

#define M_PI 3.1415926535

///////////////////////////////////////////////////////////////////////////////

AIAgent::AIAgent(IRaceController& raceController,
                 ActionObject& actionObject, 
                 PhysicalObject& physicalObject)
      : m_raceController(raceController),
      m_actionObject(actionObject),
      m_physicalObject(physicalObject),
      m_currState(AS_GET_NEXT_GATE),
      m_lastGateNo(actionObject.getNextGateNo())
{
}

///////////////////////////////////////////////////////////////////////////////

void AIAgent::update(float timeElapsed)
{
   switch(m_currState)
   {
   case AS_GET_NEXT_GATE:
      {
         Gate& nextGate = m_raceController.getGate(m_actionObject.getNextGateNo());

         float randPoint = (float)rand() / (float)RAND_MAX;
         randPoint = randPoint / 2.f + 0.25f;
         AABoundingBox crossingAreaBB = nextGate.getCrossingArea();

         m_gatePassPoint = D3DXVECTOR3(
            crossingAreaBB.min.x + (crossingAreaBB.max.x - crossingAreaBB.min.x) * randPoint,
            crossingAreaBB.min.y + (crossingAreaBB.max.y - crossingAreaBB.min.y) * randPoint,
            crossingAreaBB.min.z + (crossingAreaBB.max.z - crossingAreaBB.min.z) * randPoint);

         m_currState = AS_WAS_GATE_PASSED;

         break;
      }

   case AS_WAS_GATE_PASSED:
      {
         if (m_lastGateNo != m_actionObject.getNextGateNo())
         {
            m_lastGateNo = m_actionObject.getNextGateNo();
            m_currState = AS_GET_NEXT_GATE;
         }

         break;
      }

   default:
      {
         break;
      }
   }

   D3DXVECTOR3 currentDir = m_physicalObject.getMovable().getLookVec();
   D3DXVECTOR3 gateDir = m_gatePassPoint - m_physicalObject.getMovable().getPosition();
   float angle = calculateAngle(currentDir, gateDir);

   if (angle > 2)
   {
      m_physicalObject.rotate(DIR_RIGHT, timeElapsed);
   }
   else if (angle < -2)
   {
      m_physicalObject.rotate(DIR_LEFT, timeElapsed);
   }

   float distanceToGate = D3DXVec3Length(&gateDir);
   if (distanceToGate > 20) 
   {
      m_physicalObject.move(DIR_FORWARD, timeElapsed);
   }
}

///////////////////////////////////////////////////////////////////////////////

float AIAgent::calculateAngle(const D3DXVECTOR3& vec1, const D3DXVECTOR3& vec2) const
{
   float a1 = atan2(vec1.z, vec1.x);
   float a2 = atan2(vec2.z, vec2.x);
   float angle = (a1 - a2) * 180.0 / M_PI;

   return angle;
}

///////////////////////////////////////////////////////////////////////////////